import React, { useMemo, useState, useEffect, useCallback } from 'react';
import GameRule from '../enum/game';
import { useSelector, useDispatch } from 'react-redux';
import Piece from './piece';
import rewriteJudge from '../utils/rewrite_judge';
import './board.css';
import { changeEndingState, selectGameState } from '../gameSlice';
/**
 * @interface BoardProps 棋盘Props数据类型
 */
interface BoardProps {
    changeCheckedList: (res: CheckedListData) => void;
}

const MemoPiece = React.memo(Piece);
/**
 * @function Board 棋盘hook
 * @param {BoardProps} props props数据
 * @returns
 */
export default function Board (props: BoardProps) {
    const row: number = GameRule.BOARD_ROW;
    const column: number = GameRule.BOARD_COLUMN;
    const { changeCheckedList } = props;
    const { currentPlayer, actionChecked, ending } = useSelector(selectGameState);
    const dispatch = useDispatch();
    const [clickPosition, setClickPosition] = useState<Position>({ row: -1, column: -1 });
    const [checkedList, setCheckedList] = useState<CheckedListData>(Array(GameRule.MESH_COUNT).fill(null));

    /** 缓存点击棋盘时触发的函数处理，函数不变 */
    const handlePieceClick =  useCallback((res: ClickPieceData) => {
        setClickPosition(res);
    }, []);
    /**
     * @function setData 设置checkedList等数据，并更新game相关状态
     */
    function setData () {
        if (ending) return;
        const { row, column } = clickPosition;
        const listIndex = (column * GameRule.BOARD_ROW) + row;
        const arrC = [...checkedList];
        arrC[listIndex] = currentPlayer ? 'X' : 'O';
        const endingState: JudgeWinnerData = rewriteJudge(arrC, clickPosition);
        changeCheckedList(arrC);
        setCheckedList(arrC);
        dispatch(changeEndingState({ ending: endingState.end, endingTar: endingState.tar }));
    }
    useEffect(() => {
        setCheckedList([...actionChecked]);
    }, [actionChecked]);
    useEffect(() => {
        clickPosition.row !== -1 && setData();
    }, [clickPosition]);
    // NOTE: 用于循环渲染棋盘
    function renderPiece () {
        const boardPiece: React.ReactElement[] = [];
        for (let yC = 0; yC < column; yC++) {
            const rowPiece = [];
            for (let xC = 0; xC < row; xC++) {
                const value = (yC * row) + xC;
                /** 不变的数据：位置数据，因为返回的是一个字面量对象，所以使用useMemo，避免浅比较时返回问题 */
                const position = useMemo(() => ({ row: xC, column: yC }), []);
                const memoizedPiece = <MemoPiece
                    position={position}
                    /** 用于控制组件重新渲染的props数据 */
                    showTar={checkedList[value]}
                    checkedEffect={handlePieceClick}
                    key={`piece${value}`} />;
                rowPiece.push(memoizedPiece);
            }
            boardPiece.push(<div className="board-column" key={`boardColumn${yC}`}>{rowPiece}</div>);
        }

        return boardPiece;
    }
    return (
        <div className="board">
            {renderPiece()}
        </div>
    );
}
